using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using Microsoft.Dss.Core.Attributes;

namespace VEXRobotics
{
    /// <summary>
    /// IO Sensor Port used
    /// </summary>
    [DataContract]
    [Description("Sensor port used.")]
    public enum SensorPort
    {
        /// <summary>
        /// No port
        /// </summary>
        [Description("No port used")]
        SensorPort_None = 0,

        /// <summary>
        /// Sensor Port 1
        /// </summary>
        [Description("Sensor Port 1")]
        SensorPort_1 = 1,

        /// <summary>
        /// Sensor Port 2
        /// </summary>
        [Description("Sensor Port 2")]
        SensorPort_2 = 2,

        /// <summary>
        /// Sensor Port 3
        /// </summary>
        [Description("Sensor Port 3")]
        SensorPort_3 = 3,

        /// <summary>
        /// Sensor Port 4
        /// </summary>
        [Description("Sensor Port 4")]
        SensorPort_4 = 4,

        /// <summary>
        /// Sensor Port 5
        /// </summary>
        [Description("Sensor Port 5")]
        SensorPort_5 = 5,

        /// <summary>
        /// Sensor Port 6
        /// </summary>
        [Description("Sensor Port 6")]
        SensorPort_6 = 6,

        /// <summary>
        /// Sensor Port 7
        /// </summary>
        [Description("Sensor Port 7")]
        SensorPort_7 = 7,

        /// <summary>
        /// Sensor Port 8
        /// </summary>
        [Description("Sensor Port 8")]
        SensorPort_8 = 8,

        /// <summary>
        /// Sensor Port 9
        /// </summary>
        [Description("Sensor Port 9")]
        SensorPort_9 = 9,

        /// <summary>
        /// Sensor Port 10
        /// </summary>
        [Description("Sensor Port 10")]
        SensorPort_10 = 10,

        /// <summary>
        /// Sensor Port 11
        /// </summary>
        [Description("Sensor Port 11")]
        SensorPort_11 = 11,

        /// <summary>
        /// Sensor Port 12
        /// </summary>
        [Description("Sensor Port 12")]
        SensorPort_12 = 12,

        /// <summary>
        /// Sensor Port 13
        /// </summary>
        [Description("Sensor Port 13")]
        SensorPort_13 = 13,

        /// <summary>
        /// Sensor Port 14
        /// </summary>
        [Description("Sensor Port 14")]
        SensorPort_14 = 14,

        /// <summary>
        /// Sensor Port 15
        /// </summary>
        [Description("Sensor Port 15")]
        SensorPort_15 = 15,

        /// <summary>
        /// Sensor Port 16
        /// </summary>
        [Description("Sensor Port 16")]
        SensorPort_16 = 16,
    }

    [DataContract]
    public class SensorDefinition
    {
        /// <summary>
        /// The type of the sensor you want to subscribe to
        /// possible values: Touch, Sonar, Light, Sound, Angle, Encoder, Button, Motor
        /// 
        /// </summary>
        [DataMember]
        [Description("The sensor type (touch, sonar, light, sound, angle, encoder, button, motor).")]
        public SensorType Type;

        /// <summary>
        /// The port of the sensor you want to subscribe to
        /// possible values: 1, 2, 3, 4
        /// NOTE: Angle, Encoder, and Button sensors cannot be on port 4
        /// </summary>
        [DataMember]
        [Description("The input port to which the sensor is connected (1, 2, 3... 16).")]
        public SensorPort Port;

        /// <summary>
        /// The interrupt of the sensor you want to subscribe to
        /// possible values: 1, 2, 3, 4
        /// NOTE: Angle, Encoder, and Button sensors cannot be on port 4
        /// </summary>
        [DataMember]
        [Description("The input interrupt to which the sensor is connected (1, 2, 3... 8).")]
        public InterruptPort Interrupt;

        /// <summary>
        /// Default constructor
        /// </summary>
        public SensorDefinition() { }

        /// <summary>
        /// Build an instance and initialize it
        /// </summary>
        /// <param name="type">Type the port will be</param>
        /// <param name="port">Port number (1 based)</param>
        public SensorDefinition(SensorType type, SensorPort port)
        {
            Type = type;
            Port = port;
            Interrupt = 0;
        }

        /// <summary>
        /// Build an instance and initialize it
        /// </summary>
        /// <param name="type">Type the port will be</param>
        /// <param name="port">Port number (1 based)</param>
        /// <param name="interrupt">Interrupt number (1 based)</param>
        public SensorDefinition(SensorType type, SensorPort port, InterruptPort interrupt)
        {
            Type = type;
            Port = port;
            Interrupt = interrupt;
        }

        /// <summary>
        /// Get notification type
        /// </summary>
        /// <param name="sensor">Sensor type as a string</param>
        /// <returns>Type of the sensor</returns>
        public static SensorType GetSensorType(string sensorType)
        {
            try
            {
                return (SensorType)Enum.Parse(typeof(SensorType), sensorType, true);
            }
            catch
            {
                return SensorType.None;
            }
        }

        /// <summary>
        /// Get notification type
        /// </summary>
        /// <param name="sensor">Sensor type (as an integer)</param>
        /// <returns>Type of the sensor</returns>
        public static SensorType GetNotificationType(int sensor)
        {
            try
            {
                SensorType notificationType = (SensorType)sensor;
                return notificationType;
            }
            catch
            {
                return SensorType.None;
            }
        }

        /// <summary>
        /// Type of motor attached to the motors
        /// </summary>
        [DataContract]
        [Description("Sensor notification request.")]
        public enum PWMType
        {
            /// <summary>
            /// No Notifications selected
            /// </summary>
            [Description("No notifications.")]
            None = 0,

            /// <summary>
            /// Request Motor Angle notifications
            /// </summary>
            [Description("Motor shaft angle.")]
            Angle = 1,

            /// <summary>
            /// Request Motor power notifications
            /// </summary>
            [Description("Motor power.")]
            Motor = 2
        };

        /// <summary>
        /// Type of sensor attached to the IO Port
        /// </summary>
        [DataContract]
        [Description("Sensor notification request.")]
        public enum SensorType
        {
            /// <summary>
            /// No Notifications selected
            /// </summary>
            [Description("No notifications")]
            None = 0,

            /// <summary>
            /// Request Light On Sensor notifications
            /// </summary>
            [Description("Digital input")]
            DigitalInput = 1,

            /// <summary>
            /// Request Light On Sensor notifications
            /// </summary>
            [Description("Digital output")]
            DigitalOutput = 2,

            /// <summary>
            /// Request VEX button pressed notifications
            /// </summary>
            [Description("VEX button")]
            Button = 3,

            /// <summary>
            /// Request Touch Sensor notifications 
            /// </summary>
            [Description("VEX limit")]
            Limit = 4,

            /// <summary>
            /// Request Angle Encoder notifications
            /// </summary>
            [Description("Angle encoder")]
            Encoder = 5,

            /// <summary>
            /// Request Sonar Sensor notifications
            /// </summary>
            [Description("Ultrasonic")]
            Sonar = 6,

            /// <summary>
            /// Request Light On Sensor notifications
            /// </summary>
            [Description("Analog input")]
            AnalogInput = 7,

            /// <summary>
            /// Request Light Sensor notifications
            /// </summary>
            [Description("Light")]
            LightSensor = 8,

            /// <summary>
            /// Request Potentiometer  notifications
            /// </summary>
            [Description("Potentiometer")]
            Potentiometer = 9,

            /// <summary>
            /// Request Gyro notifications
            /// </summary>
            [Description("Gyro")]
            Gyro = 10,

            /// <summary>
            /// Request Accelerometer notifications
            /// </summary>
            [Description("Accelerometer")]
            Accelerometer = 11,

            /// <summary>
            /// Request Line Tracker notifications
            /// </summary>
            [Description("Line tracker")]
            LineTracker = 12
        }
    }
}
